#pragma once
#include <vector>
#include "Sem.hpp"
#include "Mutex.hpp"
namespace RingBufferMoudle
{
    using namespace SemMoudle;
    using namespace MutexMoudle;
    template <class T>
    class RingBuffer
    {
    public:
        RingBuffer(int cap)
            : _cap(cap), _data_sem(0), _space_sem(cap), _c_index(0), _p_index(0),_ringbuffer(cap)
        {
        }
        void Push(T&in)
        {
            //申请空间
            _space_sem.P();
            _pmutex.Lock();
            _ringbuffer[_p_index]=in;
            _p_index++;
            _p_index%=_cap;
            _pmutex.Unlock();
            //通知数据
            _data_sem.V();
        }
        void Pop(T*out)
        {
            //申请数据
            _data_sem.P();
            _cmutex.Lock();
            *out=_ringbuffer[_c_index];
            _c_index++;
            _c_index%=_cap;
            _cmutex.Unlock();
            //释放空间
            _space_sem.V();
        }
        ~RingBuffer()
        {
        }

    private:
        std::vector<T> _ringbuffer;
        int _cap; // 容量
        Sem _space_sem;
        Sem _data_sem;
        int _c_index;
        int _p_index;
        Mutex _pmutex;
        Mutex _cmutex;
    };
}